/*
 * This source code is part of TWaver 4.0
 *
 * Serva Software PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 * Copyright 2002 - 2011 Serva Software. All rights reserved.
 */

package demo.network.chassis.propagation;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.Iterator;

import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;

import twaver.AlarmSeverity;
import twaver.AlarmState;
import twaver.DataBoxSelectionEvent;
import twaver.DataBoxSelectionListener;
import twaver.Dummy;
import twaver.Element;
import twaver.Link;
import twaver.MouseActionEvent;
import twaver.Node;
import twaver.PopupMenuGenerator;
import twaver.Port;
import twaver.Rack;
import twaver.SubNetwork;
import twaver.SummingAlarmPropagator;
import twaver.TDataBox;
import twaver.TSubNetwork;
import twaver.TView;
import twaver.TWaverConst;
import twaver.network.TNetwork;
import twaver.tree.DataBoxNode;
import twaver.tree.ElementNode;
import twaver.tree.TTree;
import demo.DemoPane;

public class AlarmPropagationDemo extends DemoPane {
	
    private TDataBox box = new TDataBox("Alarm Propagation Demo");
    private TNetwork network;
    private TTree tree;
    private JPanel networkPane = new JPanel(new BorderLayout());
    private JPanel treePane = new JPanel(new BorderLayout());

    public AlarmPropagationDemo() {
        JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, treePane, networkPane);
        split.setDividerLocation(150);
        this.add(split, BorderLayout.CENTER);
        
        step1();
        step2();
        step3();
        step4();
        step5();
        step6();
        step7();
        step8();
        step9();
        
        tree.addElementNodeDoubleClickedActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				ElementNode node = (ElementNode)e.getSource(); 
				if(node.getElement() instanceof TSubNetwork){
					network.setCurrentSubNetwork((TSubNetwork)node.getElement());
				}
			}
        });
        
		tree.addTreeNodeClickedActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				MouseActionEvent event = (MouseActionEvent)e;
				if(e.getSource() instanceof DataBoxNode){
					if(event.getClickCount() == 2){
						System.out.println("DataBoxNode is double clicked");
					}
				}
			}
		});
    }

    private void step1() {
    	
        //1.create the network component.
        network = new TNetwork(box);
        network.setToolbarByName(TWaverConst.DEFAULT_TOOLBAR);
        
        //2.add the network into specified container
        networkPane.add(network, BorderLayout.CENTER);

        //3.add some elements(business objects) into the data box
        Node nodeA = new SubNetwork("A");
        nodeA.setName("I'm node A!");
        nodeA.setIcon("/demo/resource/images/server2_icon.png");
        nodeA.setImage("/demo/resource/images/server2_image.png");
        nodeA.setLocation(50, 50);
        box.addElement(nodeA); //add into box.

        Node nodeB = new Node("B");
        nodeB.setName("I'm node B!");
        nodeB.setLocation(200, 200);
        box.addElement(nodeB); //add into box.

        Link link = new Link("link", nodeA, nodeB);
        link.setName("  Telephone Line  ");
        box.addElement(link); //add into box.
    }

    private void step2() {
        //1. add some dummy elements to group the data with easy understanding hierarchy
        Dummy nodeDummy = new Dummy("node dummy");
        nodeDummy.setName("All Nodes");
        nodeDummy.addChild(box.getElementByID("A"));
        nodeDummy.addChild(box.getElementByID("B"));
        box.addElement(nodeDummy);

        Dummy linkDummy = new Dummy("link dummy");
        linkDummy.setName("All Links");
        linkDummy.addChild(box.getElementByID("link"));
        box.addElement(linkDummy);

        //2. create the tree component.
        tree = new TTree(box);
        tree.setEnsureVisibleOnSelected(true);
        
        //3. add the tree to frame.
        JScrollPane scroll = new JScrollPane(tree);
        treePane.add(scroll, BorderLayout.CENTER);
    }

    private void step3() {
        Node node = (Node) box.getElementByID("A");
        
        //1.add rack to chassis.
        Rack rack = new Rack("Rack A");
        rack.setName("Rack");
        rack.setLocation(50, 50);
        rack.setImage("/demo/network/chassis/propagation/rack.png");
        node.addChild(rack);
        box.addElement(rack);
        
        //2.add ports to rack.
        String imgPort1 = "/demo/network/chassis/propagation/port1.png";
        String imgPort2 = "/demo/network/chassis/propagation/port2.png";
        for (int module = 0; module < 4; module++) {
            Dummy dummy = new Dummy("PortDummy" + module);
            dummy.setName("module" + module);
            rack.addChild(dummy);
            box.addElement(dummy);
            for (int index = 0; index < 4; index++) {
                Port port = new Port(module + ":" + index);
                int x, y;
                if (module % 2 == 0) {
                    x = 210 + index * 24;
                } else {
                    x = 319 + index * 24;
                }
                if (module < 2) {
                    y = 16;
                    port.setImage(imgPort1);
                } else {
                    y = 37;
                    port.setImage(imgPort2);
                }
                x += rack.getLocation().x;
                y += rack.getLocation().y;
                port.setLocation(new Point(x, y));
                dummy.addChild(port);
                box.addElement(port);
            }
        }
    }

    private void step4() {
        //Create a pop-up menu factory to use throughout the application.
        PopupMenuGenerator popupMenuGenerator = new PopupMenuGenerator() {
            /**
             * Add the identifier of each of the selected objects to the menu.
             * In this example, the items added to the menu do nothing.
             * In a real application, you would probably associate an
             * implementation of the Swing Action interface with each menu item.
             */
        	public JPopupMenu generate(TView tview, MouseEvent mouseEvent) {
                //Create an empty pop-up menu.
                JPopupMenu popMenu = new JPopupMenu();
                //If the selectedObjects collection is empty, no objects are selected.
                if (tview.getDataBox().getSelectionModel().isEmpty()) {
                    popMenu.add("Nothing selected");
                } else {
                    //Access the selected objects from the selection model.
                    Iterator it = tview.getDataBox().getSelectionModel().selection();
                    while (it.hasNext()) {
                        Element element = (Element) it.next();
                        popMenu.add(element.getName());
                    }
                }
                //If menu is empty, return null.
                if (popMenu.getComponentCount() == 0) {
                    return null;
                } else {
                    return popMenu;
                }
            }
        };
        //Set the pop-up menu factory for network components
        network.setPopupMenuGenerator(popupMenuGenerator);
    }

    private void step5() {
    	network.addElementDoubleClickedActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
                Element element = (Element)e.getSource();
                JOptionPane.showMessageDialog(network, "You clicked '" + element.getName() + "'");	
			}
    	});
    	network.addBackgroundDoubleClickedActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(network, "You clicked nothing.");	
			}
    	});
    }

    private void step6() {
        //create a selection listener.
        DataBoxSelectionListener listener = new DataBoxSelectionListener() {
            public void selectionChanged(DataBoxSelectionEvent e) {
                //get the last selected element and make it visible.
                Element element = e.getBoxSelectionModel().lastElement();
                if (element != null) {
                    network.ensureVisible(element);
                }
            }
        };
        box.getSelectionModel().addDataBoxSelectionListener(listener);
    }

    private void step7() {
        //new ant set a summing propagator to the data source,
        //this will make the box propagate alarms to it's parent.
        box.setAlarmPropagator(new SummingAlarmPropagator());

        //get a port in the equipment rack.
        Port nodeA = (Port) box.getElementByID("0:0");
        AlarmState alarmState = nodeA.getAlarmState();
        //add an acknowledged alarm with critical severity.
        alarmState.addAcknowledgedAlarm(AlarmSeverity.CRITICAL);
        //add an new alarm with major severity.
        alarmState.addNewAlarm(AlarmSeverity.MAJOR);

        //get another port.
        Port nodeB = (Port) box.getElementByID("3:3");
        alarmState = nodeB.getAlarmState();
        //add 10 new alarm with critical minor.
        alarmState.increaseNewAlarm(AlarmSeverity.MINOR, 10);
    }

    private void step8() {
        //put a "attachment1" and "attachment2" icon on element A.
        Element element = box.getElementByID("A");
        element.addAttachment("attachment1");
        element.addAttachment("attachment2");
    }

    private void step9() {
        //get the link element.
        Link link = (Link)box.getElementByID("link");
        //make the link animating flowing
        link.putLinkFlowing(true);
        //set the link flowing color
        link.putLinkFlowingColor(Color.black);
        //set the link outline color
        link.putLinkOutlineColor(Color.black);
        //set the link body color.
        link.putLinkColor(Color.white);
        //set the link lable font
        link.putLabelFont(new Font("Forte", Font.BOLD, 20));
        //set the link label color 
        link.putLabelColor(Color.GREEN.darker());
        //set link type
        link.addAttachment("attachment3");
        link.addAttachment("attachment4");
        link.addAttachment("attachment5");
        link.addAttachment("attachment6");
        link.addAttachment("attachment7");
    }
}